//********************************//
//* Single-link list realisation *//
//********************************//

#include "list.h"

namespace lmf {

List::List(int ds, int s) : List_size(s), dat_size(ds)
{
	head=new Node(dat_size);
	Node* curr=head;
	for(unsigned int i=0;i<=List_size;i++) // notice the <= sign
	{
		curr->next=new Node(dat_size,curr);
		curr=curr->next;
	}
	tail=curr;
	return;
}

List::List(const List& in_list) : List_size(in_list.List_size), dat_size(in_list.dat_size)
{
    head=new Node(dat_size);
    Node* curr=head;
    iterator iter=const_cast<List&>(in_list).begin();
	for(unsigned int i=0;i<=List_size;i++) // notice the <= sign
	{
		curr->next=new Node(*iter,dat_size,curr);
		curr=curr->next;
		++iter;
	}
	tail=curr;
    return;
}

List::iterator List::begin()
{
	return iterator(head->next);
}

List::iterator List::end()
{
	return iterator(tail);
}

std::reverse_iterator<List::iterator> List::rbegin()
{
	return std::reverse_iterator<iterator>(end());
}

std::reverse_iterator<List::iterator> List::rend()
{
	return std::reverse_iterator<iterator>(begin());
}

int List::size()
{
	return List_size;
}

List& List::push_back(char* val)
{
	Node* curr=new Node(val,dat_size,tail->prev,tail);
	tail->prev->next=curr;
	tail->prev=curr;
	List_size++;
	return *this;
}

List& List::push_front(char* val)
{
	Node* curr=new Node(val,dat_size,head,head->next);
	head->next->prev=curr;
	head->next=curr;
	List_size++;
	return *this;
}

List::iterator List::insert(iterator place,char* val)
{
	Node* curr=place.curr;
	curr->prev->next=new Node(val,dat_size,curr->prev,curr);
	curr->prev=curr->prev->next;
	List_size++;
	return --place;
}

List::iterator List::remove(iterator place)
{
	Node* curr=place.curr;
	curr->prev->next=curr->next;
	curr->next->prev=curr->prev;
	place++;
	delete curr;
	List_size--;
	return place;
}

List::~List()
{
	Node* curr=head;
	Node* temp;
	while(curr!=tail)
	{
		temp=curr;
		curr=curr->next;
		delete temp;
	}
	delete tail;
	return;
}

}
